package com.xtx.air.security;

import com.xtx.air.bo.user.IUserBO;
import com.xtx.air.dao.feature.IFeatureDAO;
import com.xtx.air.dao.operator.IOperatorDAO;
import com.xtx.air.dao.user.IUserDAO;
import com.xtx.air.dataobject.OperatorDO;
import com.xtx.air.dataobject.UserDO;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

/**
 * User: hanyi
 * Date: 12-2-8
 * Time: 下午5:08
 */
public class FrontDataBaseRealm extends AuthorizingRealm {
    private IUserBO userBO;
    private IFeatureDAO featureDAO;
    protected boolean permissionsLookupEnabled = false;

    public void setUserBO(IUserBO userBO) {
        this.userBO = userBO;
    }

    public void setFeatureDAO(IFeatureDAO featureDAO) {
        this.featureDAO = featureDAO;
    }

    public void setPermissionsLookupEnabled(boolean permissionsLookupEnabled) {
        this.permissionsLookupEnabled = permissionsLookupEnabled;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //null usernames are invalid
        if (principals == null) {
            throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
        }

        String username = (String) getAvailablePrincipal(principals);
        List<String> roles = new ArrayList<String>();
        List<String> permissions = new ArrayList<String>();
        try{
            if (permissionsLookupEnabled) {
                permissions = userBO.findUserPermission(username);
            }
        }catch (Exception e) {
            // Rethrow any SQL errors as an authorization exception
            throw new AuthorizationException(e);
        }
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(new HashSet<String>(roles));
        info.setStringPermissions(new HashSet<String>(permissions));
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        String username = upToken.getUsername();
        if (username == null) {
            throw new AccountException("Null usernames are not allowed by this realm.");
        }
        SimpleAuthenticationInfo info = null;
        UserDO userDO = null;
        try {
            userDO = userBO.getUserByEmail(username);
        }catch (Exception e){
            throw new AuthenticationException("login exception",e);
        }
        if (userDO == null) {
            throw new UnknownAccountException("No account found for user [" + username + "]");
        }
        String password = userDO.getPassword();
        String salt = userDO.getSalt();
        info = new SimpleAuthenticationInfo(username, password.toCharArray(), getName());
        if (salt != null) {
            info.setCredentialsSalt(ByteSource.Util.bytes(Base64.decode(salt)));
        }
        return info;
    }
}
